### 시도
sido_sf_raw <- sf::st_read("../../docs/election_map/data/map/CTPRVN_202101/TL_SCCO_CTPRVN.shp")Reading layer `TL_SCCO_CTPRVN' from data source
`C:\docs\election_map\data\map\CTPRVN_202101\TL_SCCO_CTPRVN.shp'
using driver `ESRI Shapefile'
Simple feature collection with 17 features and 3 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 746110.3 ymin: 1458754 xmax: 1387950 ymax: 2068444
Projected CRS: PCS_ITRF2000_TM
seoul_sido_code <- sido_sf_raw %>%
mutate(CTP_KOR_NM = iconv(CTP_KOR_NM, from = "CP949", to = "UTF-8", toRaw = FALSE)) %>%
filter( str_detect(CTP_KOR_NM, "서울") ) %>%
pull(CTPRVN_CD)
### 서울특별시
sigungu_sf_raw <- sf::st_read("../../docs/election_map/data/map/SIG_202101/TL_SCCO_SIG.shp")Reading layer `TL_SCCO_SIG' from data source
`C:\docs\election_map\data\map\SIG_202101\TL_SCCO_SIG.shp'
using driver `ESRI Shapefile'
Simple feature collection with 250 features and 3 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 746110.3 ymin: 1458754 xmax: 1387948 ymax: 2068444
Projected CRS: PCS_ITRF2000_TM
sigungu_seoul_sf <- sigungu_sf_raw %>%
mutate(SIG_KOR_NM = iconv(SIG_KOR_NM, from = "CP949", to = "UTF-8", toRaw = FALSE)) %>%
mutate(CTP_KOR_NM = str_sub(SIG_CD, 1, 2)) %>%
filter(CTP_KOR_NM == seoul_sido_code) %>%
mutate(sgg_code = str_sub(SIG_CD, 1, 4)) %>%
st_simplify(dTolerance = 100, preserveTopology = TRUE)
pryr::object_size(sigungu_seoul_sf)37,136 B
sigungu_seoul_sf %>%
plot()seoul_hex <- calculate_grid(shape = sigungu_seoul_sf, grid_type = "hexagonal", seed = 3)
seoul_hex_map_raw <- assign_polygons(sigungu_seoul_sf, seoul_hex)
seoul_hex_map <- seoul_hex_map_raw %>%
dplyr::select(SIG_KOR_NM) %>%
mutate(SIG_KOR_NM = stringi::stri_escape_unicode(SIG_KOR_NM))
seoul_hex_map %>%
st_write("data/tilemap/seoul_hex_map.shp",
delete_layer=TRUE, overwrite=TRUE)Deleting layer `seoul_hex_map' using driver `ESRI Shapefile'
Writing layer `seoul_hex_map' to data source
`data/tilemap/seoul_hex_map.shp' using driver `ESRI Shapefile'
Writing 25 features with 1 fields and geometry type Polygon.
seoul_hex_map <-
st_read("data/tilemap/seoul_hex_map.shp") %>%
mutate(SIG_KOR_NM = stringi::stri_unescape_unicode(SIG_KOR_NM))Reading layer `seoul_hex_map' from data source
`C:\swc\local\data\tilemap\seoul_hex_map.shp' using driver `ESRI Shapefile'
Simple feature collection with 25 features and 1 field
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 936743 ymin: 1939324 xmax: 972635.9 ymax: 1967448
Projected CRS: PCS_ITRF2000_TM
seoul_hex_map %>%
ggplot() +
geom_sf() +
geom_sf_text(aes(geometry = geometry, label = SIG_KOR_NM),
fun.geometry = function(x) st_centroid(x) ) +
theme_void()마포구 행정구역: 26개의 법정동을 16개의 행정이 관할
SHP_code <-
read_rds("data/SHP_code.rds")
mapo_gu_code <- SHP_code %>%
filter(str_detect(CTP_KOR_NM, "서울"),
str_detect(SIG_KOR_NM, "마포"))
### 읍면동
emd_sf_raw <- sf::st_read("../../docs/election_map/data/map/EMD_202101/TL_SCCO_EMD.shp")Reading layer `TL_SCCO_EMD' from data source
`C:\docs\election_map\data\map\EMD_202101\TL_SCCO_EMD.shp'
using driver `ESRI Shapefile'
Simple feature collection with 5051 features and 3 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 746110.3 ymin: 1458754 xmax: 1387948 ymax: 2068444
Projected CRS: PCS_ITRF2000_TM
mapo_gu_sf <- emd_sf_raw %>%
mutate(EMD_KOR_NM = iconv(EMD_KOR_NM, from = "CP949", to = "UTF-8", toRaw = FALSE)) %>%
inner_join(mapo_gu_code) %>%
st_simplify(dTolerance = 50, preserveTopology = TRUE)
pryr::object_size(mapo_gu_sf)29,400 B
mapo_gu_sf %>%
plot()mapo_hex <- calculate_grid(shape = mapo_gu_sf, grid_type = "hexagonal", seed = 3)
mapo_hex_map_raw <- assign_polygons(mapo_gu_sf, mapo_hex)
mapo_hex_map <- mapo_hex_map_raw %>%
dplyr::select(SIG_KOR_NM, EMD_KOR_NM) %>%
mutate(SIG_KOR_NM = stringi::stri_escape_unicode(SIG_KOR_NM),
EMD_KOR_NM = stringi::stri_escape_unicode(EMD_KOR_NM))
mapo_hex_map %>%
st_write("data/tilemap/mapo_hex_map.shp",
delete_layer=TRUE, overwrite=TRUE)Deleting layer `mapo_hex_map' using driver `ESRI Shapefile'
Writing layer `mapo_hex_map' to data source
`data/tilemap/mapo_hex_map.shp' using driver `ESRI Shapefile'
Writing 26 features with 2 fields and geometry type Polygon.
mapo_hex_map <-
st_read("data/tilemap/mapo_hex_map.shp") %>%
mutate(SIG_KOR_NM = stringi::stri_unescape_unicode(SIG_KOR_NM),
EMD_KOR_NM = stringi::stri_unescape_unicode(EMD_KOR_NM))Reading layer `mapo_hex_map' from data source
`C:\swc\local\data\tilemap\mapo_hex_map.shp' using driver `ESRI Shapefile'
Simple feature collection with 26 features and 2 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 943022.4 ymin: 1948946 xmax: 952539.5 ymax: 1954441
Projected CRS: PCS_ITRF2000_TM
mapo_hex_map %>%
ggplot() +
geom_sf() +
geom_sf_text(aes(geometry = geometry, label = EMD_KOR_NM),
fun.geometry = function(x) st_centroid(x) ) +
theme_void()mapo_vote_tbl <- krvote::election_20220309$득표율 %>%
filter(str_detect(시도명, "서울"),
str_detect(구시군명, "마포")) %>%
group_by(구시군명, 읍면동명) %>%
summarise(더불어민주당이재명 = sum(더불어민주당이재명),
국민의힘윤석열 = sum(국민의힘윤석열),
정의당심상정 = sum(정의당심상정),
계 = sum(계)) %>%
ungroup() %>%
mutate(이재명=더불어민주당이재명/계,
윤석열=국민의힘윤석열/계,
심상정=정의당심상정/계) %>%
filter(!str_detect(읍면동명, "거소|잘못")) %>%
mutate(득표율차이 = 이재명 - 윤석열)
mapo_vote_tbl# A tibble: 18 x 10
구시군명 읍면동명 더불어민주당이재~ 국민의힘윤석열 정의당심상정 계 이재명
<chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 마포구 공덕동 8282 9631 598 18640 0.444
2 마포구 관외사전~ 17027 15755 1322 34402 0.495
3 마포구 대흥동 3417 4136 281 7900 0.433
4 마포구 도화동 5842 8017 443 14404 0.406
5 마포구 망원1동 6625 5526 562 12835 0.516
6 마포구 망원2동 5998 4795 424 11313 0.530
7 마포구 상암동 8544 8098 597 17371 0.492
8 마포구 서강동 6603 8191 558 15451 0.427
9 마포구 서교동 6412 6447 614 13591 0.472
10 마포구 성산1동 5762 4703 502 11076 0.520
11 마포구 성산2동 10423 9929 757 21287 0.490
12 마포구 신수동 5284 6745 402 12525 0.422
13 마포구 아현동 6000 8881 465 15422 0.389
14 마포구 연남동 4730 4471 442 9752 0.485
15 마포구 염리동 4445 5324 309 10148 0.438
16 마포구 용강동 5222 7015 376 12697 0.411
17 마포구 재외투표 1339 919 89 2354 0.569
18 마포구 합정동 5808 5536 559 12008 0.484
# ... with 3 more variables: 윤석열 <dbl>, 심상정 <dbl>, 득표율차이 <dbl>
mapo_vote_sf_tbl <- mapo_vote_tbl %>%
filter(! 읍면동명 %in% c("관외사전투표", "재외투표")) %>%
mutate(EMD_KOR_NM = case_when(str_detect(읍면동명, "망원") ~ "망원동",
str_detect(읍면동명, "성산") ~ "성산",
TRUE ~ 읍면동명
) )
mapo_hex_map %>%
left_join(mapo_vote_sf_tbl, by = c("EMD_KOR_NM" = "EMD_KOR_NM")) %>%
ggplot() +
geom_sf() +
geom_sf_text(aes(geometry = geometry, label = glue::glue("{EMD_KOR_NM}\n{scales::percent(득표율차이, accuracy = 0.1)}") ),
fun.geometry = function(x) st_centroid(x) ) +
theme_void()mapo_hex_map %>%
pull(EMD_KOR_NM) [1] "마포동" "토정동" "용강동" "도화동" "신공덕동" "합정동"
[7] "신정동" "구수동" "신수동" "대흥동" "당인동" "현석동"
[13] "상수동" "창전동" "염리동" "하중동" "망원동" "서교동"
[19] "동교동" "노고산동" "공덕동" "상암동" "성산동" "연남동"
[25] "중동" "아현동"
precinct_sf <- st_read("data/tilemap/HangJeongDong_ver20220309.geojson")
mapo_geojson <- precinct_sf %>%
filter(str_detect(ELEC_SIDO, "서울"),
str_detect(ELEC_GU, "마포") )
mapo_dong_g <- mapo_geojson %>%
select(ELEC_SIDO, ELEC_GU, ELEC_EMD) %>%
left_join(mapo_vote_tbl %>% filter(! 읍면동명 %in% c("관외사전투표", "재외투표")), by = c("ELEC_EMD" = "읍면동명")) %>%
ggplot() +
geom_sf(aes(geometry = geometry, fill = 득표율차이)) +
geom_sf_text(aes(geometry = geometry, label = glue::glue("{ELEC_EMD}\n{scales::percent(득표율차이, accuracy = 0.1)}") ),
fun.geometry = function(x) st_centroid(x) ) +
theme_void() +
scale_fill_gradientn( colours = c("red", "white", "blue"), labels = scales::percent) +
labs(
title = "제20대 대통령선거 서울특별시",
subtitle = "마포구 동별 득표율 차이: 이재명(%) - 윤석열(%)",
fill = "득표율 차이(%)",
caption = "데이터출처: 중앙선거관리위원회 선거통계시스템"
) +
theme(
text = element_text(family = "NanumBarunpen"),
plot.tag.position = c(0.85, .97),
legend.position = "right",
legend.title=element_text(size=15),
legend.key.size = unit(1.5, 'cm'),
legend.text=element_text(size=13),
plot.title=element_text(size=25, face="bold", family = "NanumBarunpen"),
plot.subtitle=element_text(face="bold", size=17, colour="grey10", family = "NanumBarunpen"))
mapo_dong_g
ragg::agg_png("fig/mapo_dong_g.png", width = 297, height = 210, units = "mm", res = 600, scaling = 0.85)
mapo_dong_g
dev.off()mapo_hex <- calculate_grid(shape = mapo_geojson, grid_type = "hexagonal", seed = 3)
mapo_hex_map_raw <- assign_polygons(mapo_geojson, mapo_hex)
mapo_hex_map <- mapo_hex_map_raw %>%
dplyr::select(ELEC_GU, ELEC_EMD) %>%
mutate(ELEC_GU = stringi::stri_escape_unicode(ELEC_GU),
ELEC_EMD = stringi::stri_escape_unicode(ELEC_EMD))
mapo_hex_map %>%
st_write("data/tilemap/mapo_hex_map.shp",
delete_layer=TRUE, overwrite=TRUE)mapo_hex_map <-
st_read("data/tilemap/mapo_hex_map.shp") %>%
mutate(ELEC_GU = stringi::stri_unescape_unicode(ELEC_GU),
ELEC_EMD = stringi::stri_unescape_unicode(ELEC_EMD))
mapo_dong_hex_g <- mapo_hex_map %>%
select(ELEC_GU, ELEC_EMD) %>%
left_join(mapo_vote_tbl %>% filter(! 읍면동명 %in% c("관외사전투표", "재외투표")), by = c("ELEC_EMD" = "읍면동명")) %>%
ggplot() +
geom_sf(aes(geometry = geometry, fill = 득표율차이)) +
geom_sf_text(aes(geometry = geometry, label = glue::glue("{ELEC_EMD}\n{scales::percent(득표율차이, accuracy = 0.1)}") ),
fun.geometry = function(x) st_centroid(x) ) +
theme_void() +
scale_fill_gradientn( colours = c("red", "white", "blue"), labels = scales::percent) +
labs(
title = "제20대 대통령선거 서울특별시",
subtitle = "마포구 동별 득표율 차이: 이재명(%) - 윤석열(%)",
fill = "득표율 차이(%)",
caption = "데이터출처: 중앙선거관리위원회 선거통계시스템"
) +
theme(
text = element_text(family = "NanumBarunpen"),
plot.tag.position = c(0.85, .97),
legend.position = "right",
legend.title=element_text(size=15),
legend.key.size = unit(1.5, 'cm'),
legend.text=element_text(size=13),
plot.title=element_text(size=25, face="bold", family = "NanumBarunpen"),
plot.subtitle=element_text(face="bold", size=17, colour="grey10", family = "NanumBarunpen"))
mapo_dong_hex_g
ragg::agg_png("fig/mapo_dong_hex_g.png", width = 297, height = 210, units = "mm", res = 600, scaling = 0.85)
mapo_dong_hex_g
dev.off()library(patchwork)
mapo_dong_g + mapo_dong_hex_g
ragg::agg_png("fig/mapo_dong_original_hex_g.png", width = 297, height = 210, units = "mm", res = 600, scaling = 0.85)
mapo_dong_g + mapo_dong_hex_g
dev.off()데이터 과학자 이광춘 저작
kwangchun.lee.7@gmail.com